#include <winsock2.h>
#include "xdefs.hpp"
#include "xfuncs.hpp"
#include "xwsa.hpp"
#include "xnet.hpp"
#include "xsocket.hpp"
#include "../utils/utils.hpp"
#include "../utils/util-socket.hpp"
#include "../xlln/debug-log.hpp"
#include "../xlln/xlln.hpp"
#include "../xlln/xlln-network.hpp"
#include "../xlln/wnd-sockets.hpp"

static uint32_t xlive_wsa_initialised_count = 0;

// #1
int32_t WINAPI XWSAStartup(uint16_t version_requested, WSADATA* wsa_data)
{
	TRACE_FX();
	if (!wsa_data) {
		XLLN_DEBUG_LOG(XLLN_LOG_CONTEXT_XLIVE | XLLN_LOG_LEVEL_ERROR
			, "%s wsa_data is NULL."
			, __func__
		);
		return WSAEFAULT;
	}
	
	wsa_data->iMaxSockets = 0;
	wsa_data->iMaxUdpDg = 0;
	wsa_data->lpVendorInfo = 0;
	strncpy_s(wsa_data->szDescription, "XLiveLessNess WinSock 2", WSADESCRIPTION_LEN);
	strncpy_s(wsa_data->szSystemStatus, "Running", WSASYS_STATUS_LEN);
	wsa_data->wHighVersion = version_requested;
	wsa_data->wVersion = version_requested;
	
	if (!xlive_net_initialized) {
		int32_t result = XNetStartup(0);
		if (result != ERROR_SUCCESS) {
			XLLN_DEBUG_LOG_ECODE(result, XLLN_LOG_CONTEXT_XLIVE | XLLN_LOG_LEVEL_ERROR
				, "%s XNetStartup."
				, __func__
			);
			return result;
		}
	}
	
	xlive_wsa_initialised_count++;
	
	return ERROR_SUCCESS;
}

// #2
int32_t WINAPI XWSACleanup()
{
	TRACE_FX();
	if (xlive_wsa_initialised_count == 0) {
		XLLN_DEBUG_LOG(XLLN_LOG_CONTEXT_XLIVE | XLLN_LOG_LEVEL_ERROR
			, "%s WSANOTINITIALISED."
			, __func__
		);
		WSASetLastError(WSANOTINITIALISED);
		return SOCKET_ERROR;
	}
	xlive_wsa_initialised_count--;
	WSASetLastError(ERROR_SUCCESS);
	return ERROR_SUCCESS;
}

// #16
BOOL WINAPI XWSAGetOverlappedResult(SOCKET title_socket_handle, WSAOVERLAPPED* wsa_overlapped, uint32_t* transferred_size, BOOL wait_for_completion, uint32_t* flags)
{
	TRACE_FX();
	if (!wsa_overlapped) {
		XLLN_DEBUG_LOG(XLLN_LOG_CONTEXT_XLIVE | XLLN_LOG_LEVEL_ERROR
			, "%s title_socket_handle (0x%zx) wsa_overlapped is NULL."
			, __func__
			, title_socket_handle
		);
		WSASetLastError(WSAEFAULT);
		return FALSE;
	}
	if (!transferred_size) {
		XLLN_DEBUG_LOG(XLLN_LOG_CONTEXT_XLIVE | XLLN_LOG_LEVEL_ERROR
			, "%s title_socket_handle (0x%zx) transferred_size is NULL."
			, __func__
			, title_socket_handle
		);
		WSASetLastError(WSAEFAULT);
		return FALSE;
	}
	if (!flags) {
		XLLN_DEBUG_LOG(XLLN_LOG_CONTEXT_XLIVE | XLLN_LOG_LEVEL_ERROR
			, "%s title_socket_handle (0x%zx) flags is NULL."
			, __func__
			, title_socket_handle
		);
		WSASetLastError(WSAEFAULT);
		return FALSE;
	}
	
	*transferred_size = 0;
	*flags = 0;
	
	{
		EnterCriticalSection(&xlive_critsec_sockets);
		
		auto itrTitleSocket = xlive_title_sockets.find(title_socket_handle);
		if (itrTitleSocket == xlive_title_sockets.end()) {
			
			LeaveCriticalSection(&xlive_critsec_sockets);
			
			XLLN_DEBUG_LOG(XLLN_LOG_CONTEXT_XLIVE | XLLN_LOG_LEVEL_ERROR
				, "%s title_socket_handle (0x%zx) does not exist."
				, __func__
				, title_socket_handle
			);
			WSASetLastError(WSAENOTSOCK);
			return FALSE;
		}
		
		XLIVE_TITLE_SOCKET* titleSocket = itrTitleSocket->second;
		
		if (titleSocket->recvWsaOverlapped == wsa_overlapped) {
			XLLN_DEBUG_LOG(XLLN_LOG_CONTEXT_XLIVE | XLLN_LOG_LEVEL_DEBUG
				, "%s title_socket_handle (0x%zx) RECV wsa_event (0x%zx)."
				, __func__
				, title_socket_handle
				, wsa_overlapped->hEvent
			);
			
			if (titleSocket->recvInCritSec) {
				
				LeaveCriticalSection(&xlive_critsec_sockets);
				
				XLLN_DEBUG_LOG(XLLN_LOG_CONTEXT_XLIVE | XLLN_LOG_LEVEL_ERROR
					, "%s title_socket_handle (0x%zx) an existing Recv operation is already in progress."
					, __func__
					, title_socket_handle
				);
				WSASetLastError(WSAEINPROGRESS);
				return FALSE;
			}
			
			if (titleSocket->hasShutdown & XTS_SHUTDOWN_STATE::XTS_SS_NO_RECV) {
				
				LeaveCriticalSection(&xlive_critsec_sockets);
				
				XLLN_DEBUG_LOG(XLLN_LOG_CONTEXT_XLIVE | XLLN_LOG_LEVEL_WARN
					, "%s title_socket_handle (0x%zx) socket has been shutdown for receiving."
					, __func__
					, title_socket_handle
				);
				WSASetLastError(WSAESHUTDOWN);
				return FALSE;
			}
			
			if (!titleSocket->recvTitleBuffer) {
				__debugbreak();
			}
			
			if (wait_for_completion && !titleSocket->recvPacketQueue.size()) {
				
				EnterCriticalSection(&titleSocket->recvCritSec);
				titleSocket->recvInCritSec = true;
				LeaveCriticalSection(&xlive_critsec_sockets);
				
				DWORD resultWait = WaitForSingleObject(titleSocket->recvNotify, INFINITE);
				if (resultWait != WAIT_OBJECT_0) {
					__debugbreak();
				}
				
				if (titleSocket->recvWsaOverlappedCancelled) {
					
					titleSocket->recvInCritSec = false;
					LeaveCriticalSection(&titleSocket->recvCritSec);
					
					XLLN_DEBUG_LOG(XLLN_LOG_CONTEXT_XLIVE | XLLN_LOG_LEVEL_WARN
						, "%s title_socket_handle (0x%zx) wsa_overlapped (0x%zx) has been cancelled."
						, __func__
						, title_socket_handle
						, wsa_overlapped
					);
					WSASetLastError(WSAECANCELLED);
					return FALSE;
				}
				
				if (titleSocket->hasShutdown & XTS_SHUTDOWN_STATE::XTS_SS_NO_RECV) {
					
					titleSocket->recvInCritSec = false;
					LeaveCriticalSection(&titleSocket->recvCritSec);
					
					XLLN_DEBUG_LOG(XLLN_LOG_CONTEXT_XLIVE | XLLN_LOG_LEVEL_WARN
						, "%s title_socket_handle (0x%zx) socket has been shutdown for receiving."
						, __func__
						, title_socket_handle
					);
					WSASetLastError(WSAESHUTDOWN);
					return FALSE;
				}
				
				EnterCriticalSection(&xlive_critsec_sockets);
				titleSocket->recvInCritSec = false;
				LeaveCriticalSection(&titleSocket->recvCritSec);
			}
			
			auto itrRecvPacket = titleSocket->recvPacketQueue.begin();
			if (itrRecvPacket == titleSocket->recvPacketQueue.end()) {
				
				if (wait_for_completion) {
					__debugbreak();
				}
				
				LeaveCriticalSection(&xlive_critsec_sockets);
				
				WSASetLastError(WSA_IO_INCOMPLETE);
				return FALSE;
			}
			
			titleSocket->recvWsaOverlapped = 0;
			titleSocket->recvWsaOverlappedCancelled = false;
			
			XTS_RECV_PACKET* recvPacket = *itrRecvPacket;
			
			size_t dataWholeSize = recvPacket->dataFilledSize;
			*transferred_size = recvPacket->dataFilledSize;
			bool truncated = false;
			if (*transferred_size > titleSocket->recvTitleBufferSize) {
				*transferred_size = titleSocket->recvTitleBufferSize;
				truncated = true;
			}
			
			memcpy(titleSocket->recvTitleBuffer, &recvPacket->data[recvPacket->dataConsumedSize], *transferred_size);
			
			recvPacket->dataConsumedSize += *transferred_size;
			recvPacket->dataFilledSize -= *transferred_size;
			
			if (titleSocket->recvAddressFrom) {
				sockaddr_in* sockAddrIpv4Xlive = ((sockaddr_in*)titleSocket->recvAddressFrom);
				sockAddrIpv4Xlive->sin_family = AF_INET;
				sockAddrIpv4Xlive->sin_addr.s_addr = htonl(recvPacket->remoteInstanceId);
				sockAddrIpv4Xlive->sin_port = htons(recvPacket->remoteInstanceTitlePort);
				*titleSocket->recvAddressFromSize = sizeof(sockaddr_in);
			}
			
			if (!titleSocket->recvAddressFrom && recvPacket->dataFilledSize) {
				recvPacket = 0;
			}
			else {
				titleSocket->recvPacketQueue.erase(itrRecvPacket);
			}
			
			if (titleSocket->wsaEventSelectRead != INVALID_HANDLE_VALUE && titleSocket->recvPacketQueue.size()) {
				SetEvent(titleSocket->wsaEventSelectRead);
			}
			
			titleSocket = 0;
			LeaveCriticalSection(&xlive_critsec_sockets);
			
			if (recvPacket) {
				delete recvPacket;
				recvPacket = 0;
				
				if (truncated) {
					XLLN_DEBUG_LOG(XLLN_LOG_CONTEXT_XLIVE | XLLN_LOG_LEVEL_ERROR
						, "%s title_socket_handle (0x%zx) data size (%zu) truncated to fit into Title buffer (%u)."
						, __func__
						, title_socket_handle
						, dataWholeSize
						, *transferred_size
					);
					WSASetLastError(WSAEMSGSIZE);
					return SOCKET_ERROR;
				}
			}
		}
		else if (titleSocket->sendWsaOverlapped == wsa_overlapped) {
			XLLN_DEBUG_LOG(XLLN_LOG_CONTEXT_XLIVE | XLLN_LOG_LEVEL_DEBUG
				, "%s title_socket_handle (0x%zx) SEND wsa_event (0x%zx)."
				, __func__
				, title_socket_handle
				, wsa_overlapped->hEvent
			);
			
			if (titleSocket->sendInCritSec) {
				
				LeaveCriticalSection(&xlive_critsec_sockets);
				
				XLLN_DEBUG_LOG(XLLN_LOG_CONTEXT_XLIVE | XLLN_LOG_LEVEL_ERROR
					, "%s title_socket_handle (0x%zx) an existing Send operation is already in progress."
					, __func__
					, title_socket_handle
				);
				WSASetLastError(WSAEINPROGRESS);
				return FALSE;
			}
			
			if (titleSocket->hasShutdown & XTS_SHUTDOWN_STATE::XTS_SS_NO_SEND) {
				
				LeaveCriticalSection(&xlive_critsec_sockets);
				
				XLLN_DEBUG_LOG(XLLN_LOG_CONTEXT_XLIVE | XLLN_LOG_LEVEL_WARN
					, "%s title_socket_handle (0x%zx) socket has been shutdown for sending."
					, __func__
					, title_socket_handle
				);
				WSASetLastError(WSAESHUTDOWN);
				return FALSE;
			}
			
			if (wait_for_completion && !titleSocket->sendCompleted) {
				
				EnterCriticalSection(&titleSocket->sendCritSec);
				titleSocket->sendInCritSec = true;
				LeaveCriticalSection(&xlive_critsec_sockets);
				
				DWORD resultWait = WaitForSingleObject(titleSocket->sendNotify, INFINITE);
				if (resultWait != WAIT_OBJECT_0) {
					__debugbreak();
				}
				
				if (titleSocket->sendWsaOverlappedCancelled) {
					
					titleSocket->sendInCritSec = false;
					LeaveCriticalSection(&titleSocket->sendCritSec);
					
					XLLN_DEBUG_LOG(XLLN_LOG_CONTEXT_XLIVE | XLLN_LOG_LEVEL_WARN
						, "%s title_socket_handle (0x%zx) wsa_overlapped (0x%zx) has been cancelled."
						, __func__
						, title_socket_handle
						, wsa_overlapped
					);
					WSASetLastError(WSAECANCELLED);
					return FALSE;
				}
				
				if (titleSocket->hasShutdown & XTS_SHUTDOWN_STATE::XTS_SS_NO_SEND) {
					
					titleSocket->sendInCritSec = false;
					LeaveCriticalSection(&titleSocket->sendCritSec);
					
					XLLN_DEBUG_LOG(XLLN_LOG_CONTEXT_XLIVE | XLLN_LOG_LEVEL_WARN
						, "%s title_socket_handle (0x%zx) socket has been shutdown for receiving."
						, __func__
						, title_socket_handle
					);
					WSASetLastError(WSAESHUTDOWN);
					return FALSE;
				}
				
				EnterCriticalSection(&xlive_critsec_sockets);
				titleSocket->sendInCritSec = false;
				LeaveCriticalSection(&titleSocket->sendCritSec);
			}
			
			if (!titleSocket->sendCompleted) {
				
				if (wait_for_completion) {
					__debugbreak();
				}
				
				LeaveCriticalSection(&xlive_critsec_sockets);
				
				WSASetLastError(WSA_IO_INCOMPLETE);
				return FALSE;
			}
			
			if (titleSocket->wsaEventSelectWrite != INVALID_HANDLE_VALUE) {
				SetEvent(titleSocket->wsaEventSelectWrite);
			}
			
			titleSocket->sendWsaOverlapped = 0;
			titleSocket->sendWsaOverlappedCancelled = false;
			
			*transferred_size = titleSocket->sendTransferredSize;
			bool sendTransferTruncated = titleSocket->sendTransferTruncated;
			
			titleSocket = 0;
			LeaveCriticalSection(&xlive_critsec_sockets);
			
			if (sendTransferTruncated) {
				XLLN_DEBUG_LOG(XLLN_LOG_CONTEXT_XLIVE | XLLN_LOG_LEVEL_ERROR
					, "%s title_socket_handle (0x%zx) data transfer truncated."
					, __func__
					, title_socket_handle
				);
				WSASetLastError(WSAEMSGSIZE);
				return FALSE;
			}
		}
		else {
			
			LeaveCriticalSection(&xlive_critsec_sockets);
			
			XLLN_DEBUG_LOG(XLLN_LOG_CONTEXT_XLIVE | XLLN_LOG_LEVEL_ERROR
				, "%s title_socket_handle (0x%zx) wsa_overlapped (0x%zx) does not exist for this socket."
				, __func__
				, title_socket_handle
				, wsa_overlapped
			);
			WSASetLastError(WSA_INVALID_PARAMETER);
			return FALSE;
		}
	}
	
	WSASetLastError(ERROR_SUCCESS);
	return TRUE;
}

// #17
int32_t WINAPI XWSACancelOverlappedIO(SOCKET title_socket_handle)
{
	TRACE_FX();
	{
		EnterCriticalSection(&xlive_critsec_sockets);
		
		auto itrTitleSocket = xlive_title_sockets.find(title_socket_handle);
		if (itrTitleSocket == xlive_title_sockets.end()) {
			
			LeaveCriticalSection(&xlive_critsec_sockets);
			
			XLLN_DEBUG_LOG(XLLN_LOG_CONTEXT_XLIVE | XLLN_LOG_LEVEL_ERROR
				, "%s title_socket_handle (0x%zx) does not exist."
				, __func__
				, title_socket_handle
			);
			WSASetLastError(WSAENOTSOCK);
			return SOCKET_ERROR;
		}
		
		XLIVE_TITLE_SOCKET* titleSocket = itrTitleSocket->second;
		
		{
			EnterCriticalSection(&xlln_critsec_network_send);
			
			for (auto itrSendPacket = xlln_network_send_queue.begin(); itrSendPacket != xlln_network_send_queue.end();) {
				if ((*itrSendPacket)->sourceTitleSocketHandle == titleSocket->handle) {
					delete (*itrSendPacket);
					itrSendPacket = xlln_network_send_queue.erase(itrSendPacket);
				}
				else {
					itrSendPacket++;
				}
			}
			
			LeaveCriticalSection(&xlln_critsec_network_send);
		}
		
		if (titleSocket->sendInCritSec) {
			titleSocket->sendWsaOverlappedCancelled = true;
			SetEvent(titleSocket->sendNotify);
			// Wait for it to exit.
			EnterCriticalSection(&titleSocket->sendCritSec);
			LeaveCriticalSection(&titleSocket->sendCritSec);
		}
		if (titleSocket->sendWsaOverlapped && titleSocket->sendWsaOverlapped->hEvent && titleSocket->sendWsaOverlapped->hEvent != INVALID_HANDLE_VALUE) {
			XLLN_DEBUG_LOG(XLLN_LOG_CONTEXT_XLIVE | XLLN_LOG_LEVEL_DEBUG
				, "%s title_socket_handle (0x%zx) SEND wsa_event (0x%zx)."
				, __func__
				, title_socket_handle
				, titleSocket->sendWsaOverlapped->hEvent
			);
			WSASetEvent(titleSocket->sendWsaOverlapped->hEvent);
		}
		titleSocket->sendWsaOverlapped = 0;
		titleSocket->sendWsaOverlappedCancelled = false;
		
		if (titleSocket->recvInCritSec) {
			titleSocket->recvWsaOverlappedCancelled = true;
			SetEvent(titleSocket->recvNotify);
			// Wait for it to exit.
			EnterCriticalSection(&titleSocket->recvCritSec);
			LeaveCriticalSection(&titleSocket->recvCritSec);
		}
		if (titleSocket->recvWsaOverlapped && titleSocket->recvWsaOverlapped->hEvent && titleSocket->recvWsaOverlapped->hEvent != INVALID_HANDLE_VALUE) {
			XLLN_DEBUG_LOG(XLLN_LOG_CONTEXT_XLIVE | XLLN_LOG_LEVEL_DEBUG
				, "%s title_socket_handle (0x%zx) RECV wsa_event (0x%zx)."
				, __func__
				, title_socket_handle
				, titleSocket->recvWsaOverlapped->hEvent
			);
			WSASetEvent(titleSocket->recvWsaOverlapped->hEvent);
		}
		titleSocket->recvWsaOverlapped = 0;
		titleSocket->recvWsaOverlappedCancelled = false;
		
		LeaveCriticalSection(&xlive_critsec_sockets);
	}
	
	XLLN_DEBUG_LOG(XLLN_LOG_CONTEXT_XLIVE | XLLN_LOG_LEVEL_DEBUG
		, "%s title_socket_handle (0x%zx)."
		, __func__
		, title_socket_handle
	);
	
	WSASetLastError(ERROR_SUCCESS);
	return ERROR_SUCCESS;
}

// #19
int32_t WINAPI XWSARecv(
	SOCKET title_socket_handle
	, WSABUF* wsa_buffers
	, uint32_t wsa_buffer_count
	, uint32_t* received_size
	, uint32_t* flags
	, WSAOVERLAPPED* wsa_overlapped
	, LPWSAOVERLAPPED_COMPLETION_ROUTINE wsa_completion_routine
)
{
	TRACE_FX();
	int32_t result = XWSARecvFrom(title_socket_handle, wsa_buffers, wsa_buffer_count, received_size, flags, 0, 0, wsa_overlapped, wsa_completion_routine);
	return result;
}

// #21
int32_t WINAPI XWSARecvFrom(
	SOCKET title_socket_handle
	, WSABUF* wsa_buffers
	, uint32_t wsa_buffer_count
	, uint32_t* received_size
	, uint32_t* flags
	, sockaddr* address_from
	, int32_t* address_from_size
	, WSAOVERLAPPED* wsa_overlapped
	, LPWSAOVERLAPPED_COMPLETION_ROUTINE wsa_completion_routine
)
{
	TRACE_FX();
	if (!flags) {
		XLLN_DEBUG_LOG(XLLN_LOG_CONTEXT_XLIVE | XLLN_LOG_LEVEL_ERROR
			, "%s title_socket_handle (0x%zx) flags is NULL."
			, __func__
			, title_socket_handle
		);
		WSASetLastError(WSAEFAULT);
		return SOCKET_ERROR;
	}
	if (*flags) {
		XLLN_DEBUG_LOG(XLLN_LOG_CONTEXT_XLIVE | XLLN_LOG_LEVEL_ERROR
			, "%s title_socket_handle (0x%zx) flags value (0x%08x) must be 0."
			, __func__
			, title_socket_handle
			, *flags
		);
		WSASetLastError(WSAEOPNOTSUPP);
		return SOCKET_ERROR;
	}
	if (!wsa_buffers) {
		XLLN_DEBUG_LOG(XLLN_LOG_CONTEXT_XLIVE | XLLN_LOG_LEVEL_ERROR
			, "%s title_socket_handle (0x%zx) wsa_buffers is NULL."
			, __func__
			, title_socket_handle
		);
		WSASetLastError(WSAEFAULT);
		return SOCKET_ERROR;
	}
	if (wsa_buffer_count != 1) {
		XLLN_DEBUG_LOG(XLLN_LOG_CONTEXT_XLIVE | XLLN_LOG_LEVEL_ERROR
			, "%s title_socket_handle (0x%zx) wsa_buffer_count (%u) must be 1."
			, __func__
			, title_socket_handle
			, wsa_buffer_count
		);
		WSASetLastError(WSAEOPNOTSUPP);
		return SOCKET_ERROR;
	}
	if (!wsa_buffers->buf) {
		XLLN_DEBUG_LOG(XLLN_LOG_CONTEXT_XLIVE | XLLN_LOG_LEVEL_ERROR
			, "%s title_socket_handle (0x%zx) wsa_buffers->buf is NULL."
			, __func__
			, title_socket_handle
		);
		WSASetLastError(WSAEFAULT);
		return SOCKET_ERROR;
	}
	if (!wsa_buffers->len) {
		XLLN_DEBUG_LOG(XLLN_LOG_CONTEXT_XLIVE | XLLN_LOG_LEVEL_ERROR
			, "%s title_socket_handle (0x%zx) wsa_buffers->len is 0."
			, __func__
			, title_socket_handle
		);
		WSASetLastError(WSAEFAULT);
		return SOCKET_ERROR;
	}
	if (wsa_completion_routine) {
		XLLN_DEBUG_LOG(XLLN_LOG_CONTEXT_XLIVE | XLLN_LOG_LEVEL_ERROR
			, "%s title_socket_handle (0x%zx) wsa_completion_routine must be NULL."
			, __func__
			, title_socket_handle
		);
		WSASetLastError(WSAEOPNOTSUPP);
		return SOCKET_ERROR;
	}
	if (address_from && !address_from_size) {
		XLLN_DEBUG_LOG(XLLN_LOG_CONTEXT_XLIVE | XLLN_LOG_LEVEL_ERROR
			, "%s title_socket_handle (0x%zx) address_from_size is NULL."
			, __func__
			, title_socket_handle
		);
		WSASetLastError(WSAEFAULT);
		return SOCKET_ERROR;
	}
	if (address_from && *address_from_size < sizeof(sockaddr_in)) {
		XLLN_DEBUG_LOG(XLLN_LOG_CONTEXT_XLIVE | XLLN_LOG_LEVEL_ERROR
			, "%s title_socket_handle (0x%zx): *address_from_size (0x%08x) < sizeof(sockaddr_in) (0x%zx)."
			, __func__
			, title_socket_handle
			, *address_from_size
			, (size_t)sizeof(sockaddr_in)
		);
		WSASetLastError(WSAEFAULT);
		return SOCKET_ERROR;
	}
	if (wsa_overlapped && wsa_overlapped->hEvent == INVALID_HANDLE_VALUE) {
		XLLN_DEBUG_LOG(XLLN_LOG_CONTEXT_XLIVE | XLLN_LOG_LEVEL_ERROR
			, "%s title_socket_handle (0x%zx) wsa_overlapped->hEvent is INVALID."
			, __func__
			, title_socket_handle
		);
		WSASetLastError(ERROR_INVALID_HANDLE);
		return SOCKET_ERROR;
	}
	
	if (address_from) {
		address_from->sa_family = AF_UNSPEC;
	}
	if (received_size) {
		*received_size = 0;
	}
	if (flags) {
		*flags = 0;
	}
	
	{
		EnterCriticalSection(&xlive_critsec_sockets);
		
		auto itrTitleSocket = xlive_title_sockets.find(title_socket_handle);
		if (itrTitleSocket == xlive_title_sockets.end()) {
			
			LeaveCriticalSection(&xlive_critsec_sockets);
			
			XLLN_DEBUG_LOG(XLLN_LOG_CONTEXT_XLIVE | XLLN_LOG_LEVEL_ERROR
				, "%s title_socket_handle (0x%zx) does not exist."
				, __func__
				, title_socket_handle
			);
			WSASetLastError(WSAENOTSOCK);
			return SOCKET_ERROR;
		}
		
		XLIVE_TITLE_SOCKET* titleSocket = itrTitleSocket->second;
		
		if (titleSocket->hasShutdown & XTS_SHUTDOWN_STATE::XTS_SS_NO_RECV) {
			
			LeaveCriticalSection(&xlive_critsec_sockets);
			
			XLLN_DEBUG_LOG(XLLN_LOG_CONTEXT_XLIVE | XLLN_LOG_LEVEL_WARN
				, "%s title_socket_handle (0x%zx) socket has been shutdown for receiving."
				, __func__
				, title_socket_handle
			);
			WSASetLastError(WSAESHUTDOWN);
			return SOCKET_ERROR;
		}
		
		if (titleSocket->protocol == IPPROTO_TCP) {
			if (!titleSocket->tcpIsConnected) {
				
				LeaveCriticalSection(&xlive_critsec_sockets);
				
				XLLN_DEBUG_LOG(XLLN_LOG_CONTEXT_XLIVE | XLLN_LOG_LEVEL_ERROR
					, "%s title_socket_handle (0x%zx) TCP is not connected."
					, __func__
					, title_socket_handle
				);
				WSASetLastError(WSAENOTCONN);
				return SOCKET_ERROR;
			}
		}
		
		if (titleSocket->recvInCritSec) {
			
			LeaveCriticalSection(&xlive_critsec_sockets);
			
			XLLN_DEBUG_LOG(XLLN_LOG_CONTEXT_XLIVE | XLLN_LOG_LEVEL_ERROR
				, "%s title_socket_handle (0x%zx) an existing Recv operation is in progress."
				, __func__
				, title_socket_handle
			);
			WSASetLastError(WSAEINPROGRESS);
			return SOCKET_ERROR;
		}
		if (titleSocket->recvWsaOverlapped) {
			
			LeaveCriticalSection(&xlive_critsec_sockets);
			
			XLLN_DEBUG_LOG(XLLN_LOG_CONTEXT_XLIVE | XLLN_LOG_LEVEL_ERROR
				, "%s title_socket_handle (0x%zx) an existing Recv overlapped operation is in progress."
				, __func__
				, title_socket_handle
			);
			WSASetLastError(WSAEINPROGRESS);
			return SOCKET_ERROR;
		}
		
		titleSocket->recvWsaOverlapped = 0;
		titleSocket->recvWsaOverlappedCancelled = false;
		titleSocket->recvTitleBuffer = 0;
		titleSocket->recvTitleBufferSize = 0;
		titleSocket->recvAddressFrom = 0;
		titleSocket->recvAddressFromSize = 0;
		ResetEvent(titleSocket->recvNotify);
		
		if (titleSocket->tcpIsConnected && titleSocket->tcpIsClosing && !titleSocket->recvPacketQueue.size()) {
			
			LeaveCriticalSection(&xlive_critsec_sockets);
			
			XLLN_DEBUG_LOG(XLLN_LOG_CONTEXT_XLIVE | XLLN_LOG_LEVEL_DEBUG
				, "%s title_socket_handle (0x%zx) connection is closing and there is no more data."
				, __func__
				, title_socket_handle
			);
			
			*received_size = 0;
			WSASetLastError(ERROR_SUCCESS);
			return ERROR_SUCCESS;
		}
		
		if (!wsa_overlapped) {
			
			if (!titleSocket->recvPacketQueue.size()) {
				
				if (!titleSocket->isBlocking) {
					
					LeaveCriticalSection(&xlive_critsec_sockets);
					
					WSASetLastError(WSAEWOULDBLOCK);
					return SOCKET_ERROR;
				}
				
				EnterCriticalSection(&titleSocket->recvCritSec);
				titleSocket->recvInCritSec = true;
				LeaveCriticalSection(&xlive_critsec_sockets);
				
				DWORD resultWait = WaitForSingleObject(titleSocket->recvNotify, INFINITE);
				if (resultWait != WAIT_OBJECT_0) {
					__debugbreak();
				}
				
				if (titleSocket->recvWsaOverlappedCancelled) {
					
					titleSocket->recvInCritSec = false;
					LeaveCriticalSection(&titleSocket->recvCritSec);
					
					XLLN_DEBUG_LOG(XLLN_LOG_CONTEXT_XLIVE | XLLN_LOG_LEVEL_WARN
						, "%s title_socket_handle (0x%zx) wsa_overlapped (0x%zx) has been cancelled."
						, __func__
						, title_socket_handle
						, wsa_overlapped
					);
					WSASetLastError(WSAECANCELLED);
					return SOCKET_ERROR;
				}
				
				if (titleSocket->hasShutdown & XTS_SHUTDOWN_STATE::XTS_SS_NO_RECV) {
					
					titleSocket->recvInCritSec = false;
					LeaveCriticalSection(&titleSocket->recvCritSec);
					
					XLLN_DEBUG_LOG(XLLN_LOG_CONTEXT_XLIVE | XLLN_LOG_LEVEL_WARN
						, "%s title_socket_handle (0x%zx) socket has been shutdown for receiving."
						, __func__
						, title_socket_handle
					);
					WSASetLastError(WSAESHUTDOWN);
					return SOCKET_ERROR;
				}
				
				EnterCriticalSection(&xlive_critsec_sockets);
				titleSocket->recvInCritSec = false;
				LeaveCriticalSection(&titleSocket->recvCritSec);
			}
			
			auto itrRecvPacket = titleSocket->recvPacketQueue.begin();
			if (itrRecvPacket == titleSocket->recvPacketQueue.end()) {
				if (titleSocket->tcpIsConnected && titleSocket->tcpIsClosing) {
					
					LeaveCriticalSection(&xlive_critsec_sockets);
					
					XLLN_DEBUG_LOG(XLLN_LOG_CONTEXT_XLIVE | XLLN_LOG_LEVEL_DEBUG
						, "%s title_socket_handle (0x%zx) connection is closing and there is no more data."
						, __func__
						, title_socket_handle
					);
					
					*received_size = 0;
					WSASetLastError(ERROR_SUCCESS);
					return ERROR_SUCCESS;
				}
				
				__debugbreak();
				// Should loop/wait again?
			}
			
			XTS_RECV_PACKET* recvPacket = *itrRecvPacket;
			
			size_t dataWholeSize = recvPacket->dataFilledSize;
			*received_size = recvPacket->dataFilledSize;
			bool truncated = false;
			if (*received_size > wsa_buffers->len) {
				*received_size = wsa_buffers->len;
				truncated = true;
			}
			
			memcpy(wsa_buffers->buf, &recvPacket->data[recvPacket->dataConsumedSize], *received_size);
			
			recvPacket->dataConsumedSize += *received_size;
			recvPacket->dataFilledSize -= *received_size;
			
			if (address_from) {
				sockaddr_in* sockAddrIpv4Xlive = ((sockaddr_in*)address_from);
				sockAddrIpv4Xlive->sin_family = AF_INET;
				sockAddrIpv4Xlive->sin_addr.s_addr = htonl(recvPacket->remoteInstanceId);
				sockAddrIpv4Xlive->sin_port = htons(recvPacket->remoteInstanceTitlePort);
				*address_from_size = sizeof(sockaddr_in);
			}
			
			if (!address_from && recvPacket->dataFilledSize) {
				recvPacket = 0;
			}
			else {
				titleSocket->recvPacketQueue.erase(itrRecvPacket);
			}
			
			if (titleSocket->wsaEventSelectRead != INVALID_HANDLE_VALUE && titleSocket->recvPacketQueue.size()) {
				SetEvent(titleSocket->wsaEventSelectRead);
			}
			
			titleSocket = 0;
			LeaveCriticalSection(&xlive_critsec_sockets);
			
			if (recvPacket) {
				delete recvPacket;
				recvPacket = 0;
				
				if (truncated) {
					XLLN_DEBUG_LOG(XLLN_LOG_CONTEXT_XLIVE | XLLN_LOG_LEVEL_ERROR
						, "%s title_socket_handle (0x%zx) data size (%zu) truncated to fit into Title buffer (%u)."
						, __func__
						, title_socket_handle
						, dataWholeSize
						, *received_size
					);
					WSASetLastError(WSAEMSGSIZE);
					return SOCKET_ERROR;
				}
			}
		}
		else {
			titleSocket->recvWsaOverlapped = wsa_overlapped;
			titleSocket->recvTitleBuffer = (uint8_t*)wsa_buffers->buf;
			titleSocket->recvTitleBufferSize = wsa_buffers->len;
			if (address_from) {
				titleSocket->recvAddressFrom = address_from;
				titleSocket->recvAddressFromSize = address_from_size;
			}
			
			if (titleSocket->recvPacketQueue.size()) {
				if (titleSocket->recvWsaOverlapped && titleSocket->recvWsaOverlapped->hEvent && titleSocket->recvWsaOverlapped->hEvent != INVALID_HANDLE_VALUE) {
					WSASetEvent(titleSocket->recvWsaOverlapped->hEvent);
				}
			}
			
			LeaveCriticalSection(&xlive_critsec_sockets);
			
			XLLN_DEBUG_LOG(XLLN_LOG_CONTEXT_XLIVE | XLLN_LOG_LEVEL_DEBUG
				, "%s title_socket_handle (0x%zx) wsa_overlapped->hEvent (0x%zx)."
				, __func__
				, title_socket_handle
				, wsa_overlapped->hEvent
			);
			
			WSASetLastError(WSA_IO_PENDING);
			return SOCKET_ERROR;
		}
	}
	
	WSASetLastError(ERROR_SUCCESS);
	return ERROR_SUCCESS;
}

// #23
int32_t WINAPI XWSASend(
	SOCKET title_socket_handle
	, WSABUF* wsa_buffers
	, uint32_t wsa_buffer_count
	, uint32_t* sent_size
	, uint32_t flags
	, WSAOVERLAPPED* wsa_overlapped
	, LPWSAOVERLAPPED_COMPLETION_ROUTINE wsa_completion_routine
)
{
	TRACE_FX();
	int32_t result = XWSASendTo(title_socket_handle, wsa_buffers, wsa_buffer_count, sent_size, flags, 0, 0, wsa_overlapped, wsa_completion_routine);
	return result;
}

// #25
int32_t WINAPI XWSASendTo(
	SOCKET title_socket_handle
	// each buffer is essentially its own message afaik. so wrap each one.
	, WSABUF* wsa_buffers
	, uint32_t wsa_buffer_count
	, uint32_t* sent_size
	, uint32_t flags
	, const sockaddr* address_to
	, int32_t address_to_size
	, WSAOVERLAPPED* wsa_overlapped
	, LPWSAOVERLAPPED_COMPLETION_ROUTINE wsa_completion_routine
)
{
	TRACE_FX();
	if (flags) {
		XLLN_DEBUG_LOG(XLLN_LOG_CONTEXT_XLIVE | XLLN_LOG_LEVEL_ERROR
			, "%s title_socket_handle (0x%zx) flags (0x%08x) must be 0."
			, __func__
			, flags
			, title_socket_handle
		);
		WSASetLastError(WSAEOPNOTSUPP);
		return SOCKET_ERROR;
	}
	if (!wsa_buffers) {
		XLLN_DEBUG_LOG(XLLN_LOG_CONTEXT_XLIVE | XLLN_LOG_LEVEL_ERROR
			, "%s title_socket_handle (0x%zx) wsa_buffers is NULL."
			, __func__
			, title_socket_handle
		);
		WSASetLastError(WSAEFAULT);
		return SOCKET_ERROR;
	}
	if (!wsa_buffer_count) {
		XLLN_DEBUG_LOG(XLLN_LOG_CONTEXT_XLIVE | XLLN_LOG_LEVEL_ERROR
			, "%s title_socket_handle (0x%zx) wsa_buffer_count is 0."
			, __func__
			, title_socket_handle
			, wsa_buffer_count
		);
		WSASetLastError(WSAEFAULT);
		return SOCKET_ERROR;
	}
	for (uint32_t iWsaBuffer = 0; iWsaBuffer < wsa_buffer_count; iWsaBuffer++) {
		if (!wsa_buffers[iWsaBuffer].buf) {
			XLLN_DEBUG_LOG(XLLN_LOG_CONTEXT_XLIVE | XLLN_LOG_LEVEL_ERROR
				, "%s title_socket_handle (0x%zx) wsa_buffers[%u].buf is NULL."
				, __func__
				, title_socket_handle
				, iWsaBuffer
			);
			WSASetLastError(WSAEFAULT);
			return SOCKET_ERROR;
		}
		if (!wsa_buffers[iWsaBuffer].len) {
			XLLN_DEBUG_LOG(XLLN_LOG_CONTEXT_XLIVE | XLLN_LOG_LEVEL_ERROR
				, "%s title_socket_handle (0x%zx) wsa_buffers[%u].len is 0."
				, __func__
				, title_socket_handle
				, iWsaBuffer
			);
			WSASetLastError(WSAEFAULT);
			return SOCKET_ERROR;
		}
	}
	if (wsa_completion_routine) {
		XLLN_DEBUG_LOG(XLLN_LOG_CONTEXT_XLIVE | XLLN_LOG_LEVEL_ERROR
			, "%s title_socket_handle (0x%zx) wsa_completion_routine must be NULL."
			, __func__
			, title_socket_handle
		);
		WSASetLastError(WSAEOPNOTSUPP);
		return SOCKET_ERROR;
	}
	if (address_to && address_to_size < sizeof(sockaddr_in)) {
		XLLN_DEBUG_LOG(XLLN_LOG_CONTEXT_XLIVE | XLLN_LOG_LEVEL_ERROR
			, "%s title_socket_handle (0x%zx): address_to_size (0x%08x) < sizeof(sockaddr_in) (0x%zx)."
			, __func__
			, title_socket_handle
			, address_to_size
			, (size_t)sizeof(sockaddr_in)
		);
		WSASetLastError(WSAEFAULT);
		return SOCKET_ERROR;
	}
	if (address_to && address_to->sa_family != AF_INET) {
		XLLN_DEBUG_LOG(XLLN_LOG_CONTEXT_XLIVE | XLLN_LOG_LEVEL_ERROR
			, "%s title_socket_handle (0x%zx) bind on unsupported socket address family 0x%04hx."
			, __func__
			, title_socket_handle
			, address_to->sa_family
		);
		WSASetLastError(WSAEAFNOSUPPORT);
		return SOCKET_ERROR;
	}
	if (wsa_overlapped && wsa_overlapped->hEvent == INVALID_HANDLE_VALUE) {
		XLLN_DEBUG_LOG(XLLN_LOG_CONTEXT_XLIVE | XLLN_LOG_LEVEL_ERROR
			, "%s title_socket_handle (0x%zx) wsa_overlapped->hEvent is INVALID."
			, __func__
			, title_socket_handle
		);
		WSASetLastError(ERROR_INVALID_HANDLE);
		return SOCKET_ERROR;
	}
	
	if (sent_size) {
		*sent_size = 0;
	}
	
	{
		EnterCriticalSection(&xlive_critsec_sockets);
		
		auto itrTitleSocket = xlive_title_sockets.find(title_socket_handle);
		if (itrTitleSocket == xlive_title_sockets.end()) {
			
			LeaveCriticalSection(&xlive_critsec_sockets);
			
			XLLN_DEBUG_LOG(XLLN_LOG_CONTEXT_XLIVE | XLLN_LOG_LEVEL_ERROR
				, "%s title_socket_handle (0x%zx) does not exist."
				, __func__
				, title_socket_handle
			);
			WSASetLastError(WSAENOTSOCK);
			return SOCKET_ERROR;
		}
		
		XLIVE_TITLE_SOCKET* titleSocket = itrTitleSocket->second;
		
		if (titleSocket->hasShutdown & XTS_SHUTDOWN_STATE::XTS_SS_NO_SEND) {
			
			LeaveCriticalSection(&xlive_critsec_sockets);
			
			XLLN_DEBUG_LOG(XLLN_LOG_CONTEXT_XLIVE | XLLN_LOG_LEVEL_WARN
				, "%s title_socket_handle (0x%zx) socket has been shutdown for sending."
				, __func__
				, title_socket_handle
			);
			WSASetLastError(WSAESHUTDOWN);
			return SOCKET_ERROR;
		}
		
		if (titleSocket->sendInCritSec) {
			
			LeaveCriticalSection(&xlive_critsec_sockets);
			
			XLLN_DEBUG_LOG(XLLN_LOG_CONTEXT_XLIVE | XLLN_LOG_LEVEL_ERROR
				, "%s title_socket_handle (0x%zx) an existing Send operation is in progress."
				, __func__
				, title_socket_handle
			);
			WSASetLastError(WSAEINPROGRESS);
			return SOCKET_ERROR;
		}
		
		if (titleSocket->sendWsaOverlapped) {
			
			LeaveCriticalSection(&xlive_critsec_sockets);
			
			XLLN_DEBUG_LOG(XLLN_LOG_CONTEXT_XLIVE | XLLN_LOG_LEVEL_ERROR
				, "%s title_socket_handle (0x%zx) an existing Send overlapped operation is in progress."
				, __func__
				, title_socket_handle
			);
			WSASetLastError(WSAEINPROGRESS);
			return SOCKET_ERROR;
		}
		
		uint32_t instanceId = 0;
		uint16_t instanceTitlePort = 0;
		
		if (titleSocket->protocol == IPPROTO_TCP) {
			if (address_to) {
				LeaveCriticalSection(&xlive_critsec_sockets);
				
				XLLN_DEBUG_LOG(XLLN_LOG_CONTEXT_XLIVE | XLLN_LOG_LEVEL_FATAL
					, "(RESEARCH) %s TCP title_socket_handle (0x%zx) address_to is set."
					, __func__
					, title_socket_handle
				);
				WSASetLastError(WSAEINVAL);
				return SOCKET_ERROR;
			}
			
			if (!titleSocket->tcpIsConnected) {
				
				LeaveCriticalSection(&xlive_critsec_sockets);
				
				XLLN_DEBUG_LOG(XLLN_LOG_CONTEXT_XLIVE | XLLN_LOG_LEVEL_ERROR
					, "%s title_socket_handle (0x%zx) TCP is not connected."
					, __func__
					, title_socket_handle
				);
				WSASetLastError(WSAENOTCONN);
				return SOCKET_ERROR;
			}
			
			instanceId = titleSocket->tcpRemoteInstanceId;
			instanceTitlePort = titleSocket->tcpRemoteTitlePort;
		}
		else {
			if (!address_to) {
				
				LeaveCriticalSection(&xlive_critsec_sockets);
				
				XLLN_DEBUG_LOG(XLLN_LOG_CONTEXT_XLIVE | XLLN_LOG_LEVEL_ERROR
					, "%s title_socket_handle (0x%zx) address_to is NULL."
					, __func__
					, title_socket_handle
				);
				WSASetLastError(WSAEDESTADDRREQ);
				return SOCKET_ERROR;
			}
			
			const uint32_t ipv4NBO = ((sockaddr_in*)address_to)->sin_addr.s_addr;
			instanceId = ntohl(ipv4NBO);
			instanceTitlePort = GetSockAddrPort((const SOCKADDR_STORAGE*)address_to);
		}
		
		if (instanceId == INADDR_ANY) {
			
			LeaveCriticalSection(&xlive_critsec_sockets);
			
			XLLN_DEBUG_LOG(XLLN_LOG_CONTEXT_XLIVE | XLLN_LOG_LEVEL_ERROR
				, "%s title_socket_handle (0x%zx) instanceId is 0."
				, __func__
				, title_socket_handle
			);
			WSASetLastError(WSAEADDRNOTAVAIL);
			return SOCKET_ERROR;
		}
		
		if (instanceId == INADDR_BROADCAST && !titleSocket->udpIsBroadcastEnabled) {
			
			LeaveCriticalSection(&xlive_critsec_sockets);
			
			XLLN_DEBUG_LOG(XLLN_LOG_CONTEXT_XLIVE | XLLN_LOG_LEVEL_ERROR
				, "%s title_socket_handle (0x%zx) has not been enabled for broadcasting."
				, __func__
				, title_socket_handle
			);
			WSASetLastError(WSAEACCES);
			return SOCKET_ERROR;
		}
		
		SocketImplicitBind_(titleSocket);
		
		if (instanceTitlePort == 0) {
			
			LeaveCriticalSection(&xlive_critsec_sockets);
			
			XLLN_DEBUG_LOG(XLLN_LOG_CONTEXT_XLIVE | XLLN_LOG_LEVEL_ERROR
				, "%s title_socket_handle (0x%zx) instanceId (0x%08x) instanceTitlePort is 0."
				, __func__
				, title_socket_handle
				, instanceId
			);
			WSASetLastError(WSAEADDRNOTAVAIL);
			return SOCKET_ERROR;
		}
		
		if (address_to) {
			const size_t packetSizeWrappingSpace = 0x200;
			for (uint32_t iWsaBuffer = 0; iWsaBuffer < wsa_buffer_count; iWsaBuffer++) {
				if (wsa_buffers[iWsaBuffer].len > xlive_network_sndbuf - packetSizeWrappingSpace) {
					
					LeaveCriticalSection(&xlive_critsec_sockets);
					
					XLLN_DEBUG_LOG(XLLN_LOG_CONTEXT_XLIVE | XLLN_LOG_LEVEL_ERROR
						, "%s title_socket_handle (0x%zx) packet size is too big: wsa_buffers[%u].len (0x%08x) > xlive_network_sndbuf (0x%08x) - (packetSizeWrappingSpace) (0x%zx)."
						, __func__
						, title_socket_handle
						, iWsaBuffer
						, wsa_buffers[iWsaBuffer].len
						, xlive_network_sndbuf
						, packetSizeWrappingSpace
					);
					
					WSASetLastError(WSAEMSGSIZE);
					return SOCKET_ERROR;
				}
			}
		}
		
		titleSocket->sendWsaOverlapped = 0;
		titleSocket->sendWsaOverlappedCancelled = false;
		titleSocket->sendPacketCount = 0;
		titleSocket->sendTransferredSize = 0;
		titleSocket->sendTransferTruncated = false;
		titleSocket->sendCompleted = false;
		ResetEvent(titleSocket->sendNotify);
		
		if (instanceId == INADDR_LOOPBACK || instanceId == xlln_global_instance_id) {
			SOCKET titleSocketHandleDestination = INVALID_SOCKET;
			
			for (auto itrTitleSocketDestination : xlive_title_sockets) {
				XLIVE_TITLE_SOCKET* titleSocketDestination = itrTitleSocketDestination.second;
				if (titleSocket->protocol == IPPROTO_TCP && !address_to && !titleSocketDestination->tcpIsConnected) {
					continue;
				}
				if (titleSocketDestination->portActual == instanceTitlePort) {
					if (!(titleSocketDestination->hasShutdown & XTS_SHUTDOWN_STATE::XTS_SS_NO_RECV)) {
						titleSocketHandleDestination = titleSocketDestination->handle;
					}
					break;
				}
			}
			
			if (titleSocketHandleDestination == INVALID_SOCKET) {
				
				LeaveCriticalSection(&xlive_critsec_sockets);
				
				XLLN_DEBUG_LOG(XLLN_LOG_CONTEXT_XLIVE | XLLN_LOG_LEVEL_ERROR
					, "%s title_socket_handle (0x%zx) attempted send to unused local instanceTitlePort (%hu)."
					, __func__
					, title_socket_handle
					, instanceTitlePort
				);
				WSASetLastError(WSAEHOSTUNREACH);
				return SOCKET_ERROR;
			}
			
			for (uint32_t iWsaBuffer = 0; iWsaBuffer < wsa_buffer_count; iWsaBuffer++) {
				
				size_t packetCount = wsa_buffers[iWsaBuffer].len / titleSocket->socketOptions[SO_SNDBUF];
				if (wsa_buffers[iWsaBuffer].len > packetCount * titleSocket->socketOptions[SO_SNDBUF]) {
					packetCount++;
				}
				
				XTS_RECV_PACKET** recvPackets = new XTS_RECV_PACKET*[packetCount];
				size_t iData = 0;
				
				for (size_t iPacket = 0; iPacket < packetCount; iPacket++) {
					recvPackets[iPacket] = new XTS_RECV_PACKET(iPacket == packetCount - 1 ? wsa_buffers[iWsaBuffer].len - iData : titleSocket->socketOptions[SO_SNDBUF]);
					
					memcpy(recvPackets[iPacket]->data, &(wsa_buffers[iWsaBuffer].buf[iData]), recvPackets[iPacket]->dataSize);
					recvPackets[iPacket]->dataFilledSize = recvPackets[iPacket]->dataSize;
					
					recvPackets[iPacket]->remoteInstanceId = xlln_global_instance_id;
					recvPackets[iPacket]->remoteInstanceTitlePort = titleSocket->portActual;
					
					iData += recvPackets[iPacket]->dataSize;
				}
				
				XLLN_DEBUG_LOG(XLLN_LOG_CONTEXT_XLIVE | XLLN_LOG_LEVEL_DEBUG
					, "%s title_socket_handle (0x%zx) submitting packet(s) (%zu) to local title_socket_handle (0x%zx)."
					, __func__
					, title_socket_handle
					, packetCount
					, titleSocketHandleDestination
				);
				
				for (size_t iPacket = 0; iPacket < packetCount; iPacket++) {
					
					// TODO If one of many fails then that violates the TCP protocol requirements, also might apply to iWsaBuffer too?
					bool resultSubmit = SubmitDataToTitleSocketHandle_(titleSocketHandleDestination, recvPackets[iPacket]);
					if (!resultSubmit) {
						delete recvPackets[iPacket];
					}
					recvPackets[iPacket] = 0;
				}
				
				delete[] recvPackets;
				recvPackets = 0;
				
				titleSocket->sendTransferredSize += iData;
			}
			
			titleSocket->sendCompleted = true;
			
			if (sent_size) {
				*sent_size = titleSocket->sendTransferredSize;
			}
			
			if (!wsa_overlapped) {
				
				if (titleSocket->wsaEventSelectWrite != INVALID_HANDLE_VALUE) {
					SetEvent(titleSocket->wsaEventSelectWrite);
				}
				
				LeaveCriticalSection(&xlive_critsec_sockets);
				
				WSASetLastError(ERROR_SUCCESS);
				return ERROR_SUCCESS;
			}
			else {
				titleSocket->sendWsaOverlapped = wsa_overlapped;
				
				SetEvent(titleSocket->sendNotify);
				if (titleSocket->sendWsaOverlapped && titleSocket->sendWsaOverlapped->hEvent && titleSocket->sendWsaOverlapped->hEvent != INVALID_HANDLE_VALUE) {
					WSASetEvent(titleSocket->sendWsaOverlapped->hEvent);
				}
				
				titleSocket->selectNotifyWritePending = true;
				SetEvent(titleSocket->selectNotifyWrite);
				
				LeaveCriticalSection(&xlive_critsec_sockets);
				
				XLLN_DEBUG_LOG(XLLN_LOG_CONTEXT_XLIVE | XLLN_LOG_LEVEL_DEBUG
					, "%s title_socket_handle (0x%zx) wsa_overlapped->hEvent (0x%zx)."
					, __func__
					, title_socket_handle
					, wsa_overlapped->hEvent
				);
				
				WSASetLastError(WSA_IO_PENDING);
				return SOCKET_ERROR;
			}
		}
		
		if (!address_to) {
			if (!wsa_overlapped && !titleSocket->isBlocking) {
				uint16_t oldestSequenceId = 0;
				if (
					titleSocket->tcpSendQueue.size() >= xlln_tcp_send_queue_max
					|| (
						titleSocket->tcpSendQueue.size()
						&& ((oldestSequenceId = (*titleSocket->tcpSendQueue.begin())->sequenceId), true)
						&& (
							((titleSocket->tcpSendSequenceId - xlln_tcp_send_queue_max) > titleSocket->tcpSendSequenceId)
							? (
								oldestSequenceId <= (titleSocket->tcpSendSequenceId - xlln_tcp_send_queue_max)
								&& oldestSequenceId >= titleSocket->tcpSendSequenceId
							)
							: (
								oldestSequenceId <= (titleSocket->tcpSendSequenceId - xlln_tcp_send_queue_max)
								|| oldestSequenceId >= titleSocket->tcpSendSequenceId
							)
						)
					)
				) {
					LeaveCriticalSection(&xlive_critsec_sockets);
					
					XLLN_DEBUG_LOG(XLLN_LOG_CONTEXT_XLIVE | XLLN_LOG_LEVEL_DEBUG
						, "%s title_socket_handle (0x%zx) WSAEWOULDBLOCK."
						, __func__
						, title_socket_handle
					);
					
					WSASetLastError(WSAEWOULDBLOCK);
					return SOCKET_ERROR;
				}
			}
			
			for (uint32_t iWsaBuffer = 0; iWsaBuffer < wsa_buffer_count; iWsaBuffer++) {
				
				// 576 (minimum maximum reassembly buffer size) minus maximum 60-byte IP header and 8-byte UDP header.
				const size_t packetSizeMax = 576 - 68 - sizeof(XllnNetworkPacket::TYPE) - sizeof(XllnNetworkPacket::TCP_SEQUENCED_DATA);
				
				size_t packetCount = wsa_buffers[iWsaBuffer].len / packetSizeMax;
				if (wsa_buffers[iWsaBuffer].len > packetCount * packetSizeMax) {
					packetCount++;
				}
				
				size_t iDataBuffer = 0;
				
				for (size_t iPacket = 0; iPacket < packetCount; iPacket++) {
					
					XTS_TCP_SEND_SEQUENCE_INFO* sendSequenceInfo = new XTS_TCP_SEND_SEQUENCE_INFO;
					sendSequenceInfo->sequenceId = titleSocket->tcpSendSequenceId++;
					{
						XLLN_NET_SEND_PACKET_INFO* sendPacket = new XLLN_NET_SEND_PACKET_INFO;
						sendPacket->destinationInstanceId = instanceId;
						{
							const size_t packetSizeType = sizeof(XllnNetworkPacket::TYPE);
							const size_t packetSizeTypeTcpSequencedData = sizeof(XllnNetworkPacket::TCP_SEQUENCED_DATA);
							const size_t packetSizeTitlePayload = (iPacket == packetCount - 1 ? wsa_buffers[iWsaBuffer].len - iDataBuffer : packetSizeMax);
							const size_t packetSizeTotal = packetSizeType + packetSizeTypeTcpSequencedData + packetSizeTitlePayload;
							
							XLLN_DEBUG_LOG(XLLN_LOG_CONTEXT_XLIVE | XLLN_LOG_LEVEL_DEBUG
								, "%s title_socket_handle (0x%zx) packetSizeTitlePayload (0x%zx)."
								, __func__
								, title_socket_handle
								, packetSizeTitlePayload
							);
							
							uint8_t* sendData = new uint8_t[packetSizeTotal];
							{
								size_t iData = 0;
								
								XllnNetworkPacket::TYPE &packetType = *(XllnNetworkPacket::TYPE*)&sendData[iData];
								iData += packetSizeType;
								packetType = XllnNetworkPacket::TYPE::XLLN_NPT_TCP_SEQUENCED_DATA;
								
								XllnNetworkPacket::TCP_SEQUENCED_DATA &packetTcpSequencedData = *(XllnNetworkPacket::TCP_SEQUENCED_DATA*)&sendData[iData];
								iData += packetSizeTypeTcpSequencedData;
								packetTcpSequencedData.titlePacket.instanceId = xlln_global_instance_id;
								packetTcpSequencedData.titlePacket.titlePortSource = titleSocket->portActual;
								packetTcpSequencedData.titlePacket.titlePortDestination = instanceTitlePort;
								packetTcpSequencedData.dataSize = (uint32_t)packetSizeTitlePayload;
								packetTcpSequencedData.sequenceId = sendSequenceInfo->sequenceId;
								
								memcpy(&sendData[iData], &(wsa_buffers[iWsaBuffer].buf[iDataBuffer]), packetSizeTitlePayload);
								iDataBuffer += packetSizeTitlePayload;
							}
							
							sendPacket->data = sendData;
							sendPacket->dataSize = packetSizeTotal;
						}
						
						sendSequenceInfo->sendPacket = sendPacket;
					}
					titleSocket->tcpSendQueue.push_back(sendSequenceInfo);
				}
				
				titleSocket->sendTransferredSize += wsa_buffers[iWsaBuffer].len;
			}
			
			SetEvent(xlln_tcp_sockets_update);
			
			{
				uint16_t oldestSequenceId = 0;
				if (!(
					titleSocket->tcpSendQueue.size() >= xlln_tcp_send_queue_max
					|| (
						titleSocket->tcpSendQueue.size()
						&& ((oldestSequenceId = (*titleSocket->tcpSendQueue.begin())->sequenceId), true)
						&& (
							((titleSocket->tcpSendSequenceId - xlln_tcp_send_queue_max) > titleSocket->tcpSendSequenceId)
							? (
								oldestSequenceId <= (titleSocket->tcpSendSequenceId - xlln_tcp_send_queue_max)
								&& oldestSequenceId >= titleSocket->tcpSendSequenceId
							)
							: (
								oldestSequenceId <= (titleSocket->tcpSendSequenceId - xlln_tcp_send_queue_max)
								|| oldestSequenceId >= titleSocket->tcpSendSequenceId
							)
						)
					)
				)) {
					titleSocket->sendCompleted = true;
					
					SetEvent(titleSocket->sendNotify);
					if (titleSocket->sendWsaOverlapped && titleSocket->sendWsaOverlapped->hEvent && titleSocket->sendWsaOverlapped->hEvent != INVALID_HANDLE_VALUE) {
						WSASetEvent(titleSocket->sendWsaOverlapped->hEvent);
					}
					
					titleSocket->selectNotifyWritePending = true;
					SetEvent(titleSocket->selectNotifyWrite);
				}
			}
			
			XLLN_DEBUG_LOG(XLLN_LOG_CONTEXT_XLIVE | XLLN_LOG_LEVEL_DEBUG
				, "%s title_socket_handle (0x%zx) TCP queued packet for sending with sequenceId (%hu)."
				, __func__
				, title_socket_handle
				, titleSocket->tcpSendSequenceId - 1
			);
		}
		else {
			for (uint32_t iWsaBuffer = 0; iWsaBuffer < wsa_buffer_count; iWsaBuffer++) {
				XLLN_NET_SEND_PACKET_INFO* sendPacket = new XLLN_NET_SEND_PACKET_INFO;
				if (titleSocket->isBlocking || wsa_overlapped) {
					sendPacket->sourceTitleSocketHandle = title_socket_handle;
					titleSocket->sendPacketCount++;
				}
				sendPacket->destinationInstanceId = instanceId;
				{
					const size_t packetSizeType = sizeof(XllnNetworkPacket::TYPE);
					const size_t packetSizeTypeTitle = sizeof(XllnNetworkPacket::TITLE_PACKET);
					const size_t packetSizeTitlePayload = wsa_buffers[iWsaBuffer].len;
					const size_t packetSizeTotal = packetSizeType + packetSizeTypeTitle + packetSizeTitlePayload;
					
					uint8_t* sendData = new uint8_t[packetSizeTotal];
					{
						size_t iData = 0;
						
						XllnNetworkPacket::TYPE &packetType = *(XllnNetworkPacket::TYPE*)&sendData[iData];
						iData += packetSizeType;
						packetType = XllnNetworkPacket::TYPE::XLLN_NPT_TITLE_PACKET;
						
						XllnNetworkPacket::TITLE_PACKET &packetTitle = *(XllnNetworkPacket::TITLE_PACKET*)&sendData[iData];
						iData += packetSizeTypeTitle;
						packetTitle.instanceId = xlln_global_instance_id;
						packetTitle.titlePortSource = titleSocket->portActual;
						packetTitle.titlePortDestination = instanceTitlePort;
						
						memcpy(&sendData[iData], wsa_buffers[iWsaBuffer].buf, packetSizeTitlePayload);
					}
					
					sendPacket->data = sendData;
					sendPacket->dataSize = packetSizeTotal;
				}
				
				if (SendPacketToRemoteInstance(sendPacket)) {
					titleSocket->sendTransferredSize += wsa_buffers[iWsaBuffer].len;
				}
				else {
					if (sendPacket->sourceTitleSocketHandle != INVALID_SOCKET) {
						titleSocket->sendPacketCount--;
					}
					delete sendPacket;
					sendPacket = 0;
					
					XLLN_DEBUG_LOG(XLLN_LOG_CONTEXT_XLIVE | XLLN_LOG_LEVEL_ERROR
						, "%s title_socket_handle (0x%zx) SendPacketToRemoteInstance failed."
						, __func__
						, title_socket_handle
					);
				}
				
				sendPacket = 0;
			}
			
			if (!titleSocket->sendPacketCount) {
				LeaveCriticalSection(&xlive_critsec_sockets);
				
				WSASetLastError(WSAENETDOWN);
				return SOCKET_ERROR;
			}
		}
		
		if (!wsa_overlapped) {
			
			if (titleSocket->isBlocking) {
				EnterCriticalSection(&titleSocket->sendCritSec);
				titleSocket->sendInCritSec = true;
				LeaveCriticalSection(&xlive_critsec_sockets);
				
				DWORD resultWait = WaitForSingleObject(titleSocket->sendNotify, INFINITE);
				if (resultWait != WAIT_OBJECT_0) {
					__debugbreak();
				}
				
				if (titleSocket->sendWsaOverlappedCancelled) {
					
					titleSocket->sendInCritSec = false;
					LeaveCriticalSection(&titleSocket->sendCritSec);
					
					XLLN_DEBUG_LOG(XLLN_LOG_CONTEXT_XLIVE | XLLN_LOG_LEVEL_WARN
						, "%s title_socket_handle (0x%zx) wsa_overlapped (0x%zx) has been cancelled."
						, __func__
						, title_socket_handle
						, wsa_overlapped
					);
					WSASetLastError(WSAECANCELLED);
					return SOCKET_ERROR;
				}
				
				if (titleSocket->hasShutdown & XTS_SHUTDOWN_STATE::XTS_SS_NO_SEND) {
					
					titleSocket->sendInCritSec = false;
					LeaveCriticalSection(&titleSocket->sendCritSec);
					
					XLLN_DEBUG_LOG(XLLN_LOG_CONTEXT_XLIVE | XLLN_LOG_LEVEL_WARN
						, "%s title_socket_handle (0x%zx) socket has been shutdown for receiving."
						, __func__
						, title_socket_handle
					);
					WSASetLastError(WSAESHUTDOWN);
					return SOCKET_ERROR;
				}
				
				EnterCriticalSection(&xlive_critsec_sockets);
				titleSocket->sendInCritSec = false;
				LeaveCriticalSection(&titleSocket->sendCritSec);
			}
			else {
				// FIXME in this scenario we might want to return WSAEWOULDBLOCK to prevent the Title from filling up our network faster than we can send.
			}
			
			if (sent_size) {
				*sent_size = titleSocket->sendTransferredSize;
			}
			
			if (titleSocket->wsaEventSelectWrite != INVALID_HANDLE_VALUE) {
				SetEvent(titleSocket->wsaEventSelectWrite);
			}
			
			bool sendTransferTruncated = titleSocket->sendTransferTruncated;
			
			LeaveCriticalSection(&xlive_critsec_sockets);
			
			if (sendTransferTruncated) {
				XLLN_DEBUG_LOG(XLLN_LOG_CONTEXT_XLIVE | XLLN_LOG_LEVEL_WARN
					, "%s title_socket_handle (0x%zx) data transfer truncated."
					, __func__
					, title_socket_handle
				);
				WSASetLastError(WSAEMSGSIZE);
				return SOCKET_ERROR;
			}
		}
		else {
			titleSocket->sendWsaOverlapped = wsa_overlapped;
			
			LeaveCriticalSection(&xlive_critsec_sockets);
			
			XLLN_DEBUG_LOG(XLLN_LOG_CONTEXT_XLIVE | XLLN_LOG_LEVEL_DEBUG
				, "%s title_socket_handle (0x%zx) wsa_overlapped->hEvent (0x%zx)."
				, __func__
				, title_socket_handle
				, wsa_overlapped->hEvent
			);
			
			WSASetLastError(WSA_IO_PENDING);
			return SOCKET_ERROR;
		}
	}
	
	WSASetLastError(ERROR_SUCCESS);
	return ERROR_SUCCESS;
}

// #28
void WINAPI XWSASetLastError(int32_t error_code)
{
	TRACE_FX();
	XLLN_DEBUG_LOG_ECODE(error_code, XLLN_LOG_CONTEXT_XLIVE | XLLN_LOG_LEVEL_DEBUG
		, "%s"
		, __func__
	);
	WSASetLastError(error_code);
}

// #29
WSAEVENT WINAPI XWSACreateEvent()
{
	TRACE_FX();
	WSAEVENT wsa_event = WSACreateEvent();
	// Essentially equivalent to:
	//WSAEVENT wsa_event = CreateEvent(NULL, TRUE, FALSE, NULL);
	if (!wsa_event) {
		int32_t errorCode = WSAGetLastError();
		XLLN_DEBUG_LOG_ECODE(errorCode, XLLN_LOG_CONTEXT_XLIVE | XLLN_LOG_LEVEL_ERROR
			, "%s failed."
			, __func__
		);
	}
	else {
		XLLN_DEBUG_LOG(XLLN_LOG_CONTEXT_XLIVE | XLLN_LOG_LEVEL_DEBUG
			, "%s wsa_event (0x%zx)."
			, __func__
			, wsa_event
		);
	}
	return wsa_event;
}

// #30
BOOL WINAPI XWSACloseEvent(WSAEVENT wsa_event)
{
	TRACE_FX();
	if (!wsa_event || wsa_event == INVALID_HANDLE_VALUE) {
		XLLN_DEBUG_LOG(XLLN_LOG_CONTEXT_XLIVE | XLLN_LOG_LEVEL_ERROR
			, "%s wsa_event is INVALID."
			, __func__
		);
		WSASetLastError(WSA_INVALID_HANDLE);
		return FALSE;
	}
	BOOL result = WSACloseEvent(wsa_event);
	if (!result) {
		int32_t errorCode = WSAGetLastError();
		XLLN_DEBUG_LOG_ECODE(errorCode, XLLN_LOG_CONTEXT_XLIVE | XLLN_LOG_LEVEL_ERROR
			, "%s failed."
			, __func__
		);
	}
	else {
		XLLN_DEBUG_LOG(XLLN_LOG_CONTEXT_XLIVE | XLLN_LOG_LEVEL_DEBUG
			, "%s wsa_event (0x%zx)."
			, __func__
			, wsa_event
		);
	}
	return result;
}

// #31
BOOL WINAPI XWSASetEvent(WSAEVENT wsa_event)
{
	TRACE_FX();
	if (!wsa_event || wsa_event == INVALID_HANDLE_VALUE) {
		XLLN_DEBUG_LOG(XLLN_LOG_CONTEXT_XLIVE | XLLN_LOG_LEVEL_ERROR
			, "%s wsa_event is INVALID."
			, __func__
		);
		WSASetLastError(WSA_INVALID_HANDLE);
		return FALSE;
	}
	BOOL result = WSASetEvent(wsa_event);
	if (!result) {
		int32_t errorCode = WSAGetLastError();
		XLLN_DEBUG_LOG_ECODE(errorCode, XLLN_LOG_CONTEXT_XLIVE | XLLN_LOG_LEVEL_ERROR
			, "%s failed."
			, __func__
		);
	}
	else {
		XLLN_DEBUG_LOG(XLLN_LOG_CONTEXT_XLIVE | XLLN_LOG_LEVEL_DEBUG
			, "%s wsa_event (0x%zx)."
			, __func__
			, wsa_event
		);
	}
	return result;
}

// #32
BOOL WINAPI XWSAResetEvent(WSAEVENT wsa_event)
{
	TRACE_FX();
	if (!wsa_event || wsa_event == INVALID_HANDLE_VALUE) {
		XLLN_DEBUG_LOG(XLLN_LOG_CONTEXT_XLIVE | XLLN_LOG_LEVEL_ERROR
			, "%s wsa_event is INVALID."
			, __func__
		);
		WSASetLastError(WSA_INVALID_HANDLE);
		return FALSE;
	}
	BOOL result = WSAResetEvent(wsa_event);
	if (!result) {
		int32_t errorCode = WSAGetLastError();
		XLLN_DEBUG_LOG_ECODE(errorCode, XLLN_LOG_CONTEXT_XLIVE | XLLN_LOG_LEVEL_ERROR
			, "%s failed."
			, __func__
		);
	}
	else {
		XLLN_DEBUG_LOG(XLLN_LOG_CONTEXT_XLIVE | XLLN_LOG_LEVEL_DEBUG
			, "%s wsa_event (0x%zx)."
			, __func__
			, wsa_event
		);
	}
	return result;
}

// #33
uint32_t WINAPI XWSAWaitForMultipleEvents(uint32_t event_count, const WSAEVENT* wsa_events, BOOL wait_on_all, uint32_t timeout, BOOL alertable)
{
	TRACE_FX();
	if (!event_count) {
		XLLN_DEBUG_LOG(XLLN_LOG_CONTEXT_XLIVE | XLLN_LOG_LEVEL_ERROR
			, "%s event_count is 0."
			, __func__
		);
		WSASetLastError(WSA_INVALID_PARAMETER);
		return WSA_WAIT_FAILED;
	}
	if (!wsa_events) {
		XLLN_DEBUG_LOG(XLLN_LOG_CONTEXT_XLIVE | XLLN_LOG_LEVEL_ERROR
			, "%s wsa_events is NULL."
			, __func__
		);
		WSASetLastError(WSA_INVALID_PARAMETER);
		return WSA_WAIT_FAILED;
	}
	#ifdef XLLN_DEBUG
	{
		char* printTextEvents = FormMallocString("0x%zx", wsa_events[0]);
		for (uint32_t iEvent = 1; iEvent < event_count; iEvent++) {
			char* printTextOld = printTextEvents;
			printTextEvents = FormMallocString("%s, 0x%zx", printTextOld, wsa_events[iEvent]);
			free(printTextOld);
			printTextOld = 0;
		}
		XLLN_DEBUG_LOG(XLLN_LOG_CONTEXT_XLIVE | XLLN_LOG_LEVEL_DEBUG
			, "%s wsa_events (%s), wait_on_all (%s), timeout (0x%08x), alertable (%s)."
			, __func__
			, printTextEvents
			, wait_on_all ? "TRUE" : "FALSE"
			, timeout
			, alertable ? "TRUE" : "FALSE"
		);
		free(printTextEvents);
		printTextEvents = 0;
	}
	#endif
	for (uint32_t iEvent = 0; iEvent < event_count; iEvent++) {
		if (!wsa_events[iEvent] || wsa_events[iEvent] == INVALID_HANDLE_VALUE) {
			XLLN_DEBUG_LOG(XLLN_LOG_CONTEXT_XLIVE | XLLN_LOG_LEVEL_ERROR
				, "%s wsa_events[iEvent (%u)] is INVALID."
				, __func__
				, iEvent
			);
			WSASetLastError(WSA_INVALID_HANDLE);
			return WSA_WAIT_FAILED;
		}
	}
	
	uint32_t result = WSAWaitForMultipleEvents(event_count, wsa_events, wait_on_all, timeout, alertable);
	if (result == WSA_WAIT_FAILED) {
		int32_t errorCode = WSAGetLastError();
		XLLN_DEBUG_LOG_ECODE(errorCode, XLLN_LOG_CONTEXT_XLIVE | XLLN_LOG_LEVEL_ERROR
			, "%s failed."
			, __func__
		);
	}
	else {
		XLLN_DEBUG_LOG(XLLN_LOG_CONTEXT_XLIVE | XLLN_LOG_LEVEL_DEBUG
			, "%s result (0x%x)."
			, __func__
			, result
		);
	}
	return result;
}

// #34
int32_t WINAPI XWSAFDIsSet(SOCKET title_socket_handle, fd_set* title_socket_set)
{
	TRACE_FX();
	if (!title_socket_set) {
		XLLN_DEBUG_LOG(XLLN_LOG_CONTEXT_XLIVE | XLLN_LOG_LEVEL_ERROR
			, "%s title_socket_set is NULL."
			, __func__
		);
		WSASetLastError(WSAEFAULT);
		return 0;
	}
	
	bool containsSocket = false;
	
	for (u_int iSocket = 0; iSocket < title_socket_set->fd_count; iSocket++) {
		if (title_socket_handle == title_socket_set->fd_array[iSocket]) {
			containsSocket = true;
			break;
		}
	}
	
	WSASetLastError(ERROR_SUCCESS);
	return containsSocket ? 1 : 0;
}

// #35
int32_t WINAPI XWSAEventSelect(SOCKET title_socket_handle, WSAEVENT wsa_event, uint32_t network_event_flags)
{
	TRACE_FX();
	if (!wsa_event || wsa_event == INVALID_HANDLE_VALUE) {
		XLLN_DEBUG_LOG(XLLN_LOG_CONTEXT_XLIVE | XLLN_LOG_LEVEL_ERROR
			, "%s wsa_event is null/INVALID_HANDLE_VALUE."
			, __func__
		);
		WSASetLastError(WSAEINVAL);
		return SOCKET_ERROR;
	}
	
	switch (network_event_flags) {
		case FD_READ:
		case FD_WRITE:
		case FD_OOB:
		case FD_ACCEPT:
		case FD_CONNECT:
		case FD_CLOSE:
		case 0: {
			break;
		}
		case FD_QOS:
		case FD_GROUP_QOS:
		case FD_ROUTING_INTERFACE_CHANGE:
		case FD_ADDRESS_LIST_CHANGE: {
			XLLN_DEBUG_LOG(XLLN_LOG_CONTEXT_XLIVE | XLLN_LOG_LEVEL_ERROR
				, "%s network_event_flags (0x%x) is not supported."
				, __func__
				, network_event_flags
			);
			WSASetLastError(WSAEOPNOTSUPP);
			return SOCKET_ERROR;
		}
		default: {
			XLLN_DEBUG_LOG(XLLN_LOG_CONTEXT_XLIVE | XLLN_LOG_LEVEL_ERROR
				, "%s network_event_flags (0x%x) is unknown."
				, __func__
				, network_event_flags
			);
			WSASetLastError(WSAEINVAL);
			return SOCKET_ERROR;
		}
	}
	
	{
		EnterCriticalSection(&xlive_critsec_sockets);
		
		auto itrTitleSocket = xlive_title_sockets.find(title_socket_handle);
		if (itrTitleSocket == xlive_title_sockets.end()) {
			
			LeaveCriticalSection(&xlive_critsec_sockets);
			
			XLLN_DEBUG_LOG(XLLN_LOG_CONTEXT_XLIVE | XLLN_LOG_LEVEL_ERROR
				, "%s title_socket_handle (0x%zx) does not exist."
				, __func__
				, title_socket_handle
			);
			WSASetLastError(WSAENOTSOCK);
			return SOCKET_ERROR;
		}
		
		XLIVE_TITLE_SOCKET* titleSocket = itrTitleSocket->second;
		
		if (titleSocket->isBlocking) {
			XLLN_DEBUG_LOG(XLLN_LOG_CONTEXT_XLIVE | XLLN_LOG_LEVEL_INFO
				, "%s title_socket_handle (0x%zx) socket/FIONBIO set to ASYNC implicitly."
				, __func__
				, title_socket_handle
			);
			
			titleSocket->isBlocking = false;
			titleSocket->socketIoctls[FIONBIO] = 1;
		}
		
		if (titleSocket->wsaEventSelectRead == wsa_event) {
			titleSocket->wsaEventSelectRead = WSA_INVALID_EVENT;
			if (network_event_flags != FD_READ) {
				XLLN_DEBUG_LOG(XLLN_LOG_CONTEXT_XLIVE | XLLN_LOG_LEVEL_DEBUG
					, "%s wsa_event (0x%zx) removed from FD_READ."
					, __func__
					, wsa_event
				);
			}
		}
		if (titleSocket->wsaEventSelectWrite == wsa_event) {
			titleSocket->wsaEventSelectWrite = WSA_INVALID_EVENT;
			if (network_event_flags != FD_WRITE) {
				XLLN_DEBUG_LOG(XLLN_LOG_CONTEXT_XLIVE | XLLN_LOG_LEVEL_DEBUG
					, "%s wsa_event (0x%zx) removed from FD_WRITE."
					, __func__
					, wsa_event
				);
			}
		}
		if (titleSocket->wsaEventSelectOob == wsa_event) {
			titleSocket->wsaEventSelectOob = WSA_INVALID_EVENT;
			if (network_event_flags != FD_OOB) {
				XLLN_DEBUG_LOG(XLLN_LOG_CONTEXT_XLIVE | XLLN_LOG_LEVEL_DEBUG
					, "%s wsa_event (0x%zx) removed from FD_OOB."
					, __func__
					, wsa_event
				);
			}
		}
		if (titleSocket->wsaEventSelectAccept == wsa_event) {
			titleSocket->wsaEventSelectAccept = WSA_INVALID_EVENT;
			if (network_event_flags != FD_ACCEPT) {
				XLLN_DEBUG_LOG(XLLN_LOG_CONTEXT_XLIVE | XLLN_LOG_LEVEL_DEBUG
					, "%s wsa_event (0x%zx) removed from FD_ACCEPT."
					, __func__
					, wsa_event
				);
			}
		}
		if (titleSocket->wsaEventSelectConnect == wsa_event) {
			titleSocket->wsaEventSelectConnect = WSA_INVALID_EVENT;
			if (network_event_flags != FD_CONNECT) {
				XLLN_DEBUG_LOG(XLLN_LOG_CONTEXT_XLIVE | XLLN_LOG_LEVEL_DEBUG
					, "%s wsa_event (0x%zx) removed from FD_CONNECT."
					, __func__
					, wsa_event
				);
			}
		}
		if (titleSocket->wsaEventSelectClose == wsa_event) {
			titleSocket->wsaEventSelectClose = WSA_INVALID_EVENT;
			if (network_event_flags != FD_CLOSE) {
				XLLN_DEBUG_LOG(XLLN_LOG_CONTEXT_XLIVE | XLLN_LOG_LEVEL_DEBUG
					, "%s wsa_event (0x%zx) removed from FD_CLOSE."
					, __func__
					, wsa_event
				);
			}
		}
		
		switch (network_event_flags) {
			case FD_READ: {
				if (titleSocket->wsaEventSelectRead != WSA_INVALID_EVENT) {
					XLLN_DEBUG_LOG(XLLN_LOG_CONTEXT_XLIVE | XLLN_LOG_LEVEL_DEBUG
						, "%s wsa_event (0x%zx) removed from FD_READ."
						, __func__
						, titleSocket->wsaEventSelectRead
					);
				}
				titleSocket->wsaEventSelectRead = wsa_event;
				XLLN_DEBUG_LOG(XLLN_LOG_CONTEXT_XLIVE | XLLN_LOG_LEVEL_DEBUG
					, "%s wsa_event (0x%zx) added to FD_READ."
					, __func__
					, titleSocket->wsaEventSelectRead
				);
				break;
			}
			case FD_WRITE: {
				if (titleSocket->wsaEventSelectWrite != WSA_INVALID_EVENT) {
					XLLN_DEBUG_LOG(XLLN_LOG_CONTEXT_XLIVE | XLLN_LOG_LEVEL_DEBUG
						, "%s wsa_event (0x%zx) removed from FD_WRITE."
						, __func__
						, titleSocket->wsaEventSelectWrite
					);
				}
				titleSocket->wsaEventSelectWrite = wsa_event;
				XLLN_DEBUG_LOG(XLLN_LOG_CONTEXT_XLIVE | XLLN_LOG_LEVEL_DEBUG
					, "%s wsa_event (0x%zx) added to FD_WRITE."
					, __func__
					, titleSocket->wsaEventSelectWrite
				);
				break;
			}
			case FD_OOB: {
				if (titleSocket->wsaEventSelectOob != WSA_INVALID_EVENT) {
					XLLN_DEBUG_LOG(XLLN_LOG_CONTEXT_XLIVE | XLLN_LOG_LEVEL_DEBUG
						, "%s wsa_event (0x%zx) removed from FD_OOB."
						, __func__
						, titleSocket->wsaEventSelectOob
					);
				}
				titleSocket->wsaEventSelectOob = wsa_event;
				XLLN_DEBUG_LOG(XLLN_LOG_CONTEXT_XLIVE | XLLN_LOG_LEVEL_DEBUG
					, "%s wsa_event (0x%zx) added to FD_OOB."
					, __func__
					, titleSocket->wsaEventSelectOob
				);
				break;
			}
			case FD_ACCEPT: {
				if (titleSocket->wsaEventSelectAccept != WSA_INVALID_EVENT) {
					XLLN_DEBUG_LOG(XLLN_LOG_CONTEXT_XLIVE | XLLN_LOG_LEVEL_DEBUG
						, "%s wsa_event (0x%zx) removed from FD_ACCEPT."
						, __func__
						, titleSocket->wsaEventSelectAccept
					);
				}
				titleSocket->wsaEventSelectAccept = wsa_event;
				XLLN_DEBUG_LOG(XLLN_LOG_CONTEXT_XLIVE | XLLN_LOG_LEVEL_DEBUG
					, "%s wsa_event (0x%zx) added to FD_ACCEPT."
					, __func__
					, titleSocket->wsaEventSelectAccept
				);
				break;
			}
			case FD_CONNECT: {
				if (titleSocket->wsaEventSelectConnect != WSA_INVALID_EVENT) {
					XLLN_DEBUG_LOG(XLLN_LOG_CONTEXT_XLIVE | XLLN_LOG_LEVEL_DEBUG
						, "%s wsa_event (0x%zx) removed from FD_CONNECT."
						, __func__
						, titleSocket->wsaEventSelectConnect
					);
				}
				titleSocket->wsaEventSelectConnect = wsa_event;
				XLLN_DEBUG_LOG(XLLN_LOG_CONTEXT_XLIVE | XLLN_LOG_LEVEL_DEBUG
					, "%s wsa_event (0x%zx) added to FD_CONNECT."
					, __func__
					, titleSocket->wsaEventSelectConnect
				);
				break;
			}
			case FD_CLOSE: {
				if (titleSocket->wsaEventSelectClose != WSA_INVALID_EVENT) {
					XLLN_DEBUG_LOG(XLLN_LOG_CONTEXT_XLIVE | XLLN_LOG_LEVEL_DEBUG
						, "%s wsa_event (0x%zx) removed from FD_CLOSE."
						, __func__
						, titleSocket->wsaEventSelectClose
					);
				}
				titleSocket->wsaEventSelectClose = wsa_event;
				XLLN_DEBUG_LOG(XLLN_LOG_CONTEXT_XLIVE | XLLN_LOG_LEVEL_DEBUG
					, "%s wsa_event (0x%zx) added to FD_CLOSE."
					, __func__
					, titleSocket->wsaEventSelectClose
				);
				break;
			}
		}
		
		LeaveCriticalSection(&xlive_critsec_sockets);
	}
	
	WSASetLastError(ERROR_SUCCESS);
	return ERROR_SUCCESS;
}
